<?php

namespace WebmanGrpc\Serialization;

use Google\Protobuf\Internal\Message;

/**
 * 序列化优化器
 * 
 * 提供Protobuf序列化的性能优化功能
 */
class SerializationOptimizer
{
    /**
     * 是否启用Lite模式
     * @var bool
     */
    protected static bool $liteMode = false;
    
    /**
     * 是否启用对象池
     * @var bool
     */
    protected static bool $poolEnabled = true;
    
    /**
     * 是否启用序列化缓存
     * @var bool
     */
    protected static bool $cacheEnabled = true;
    
    /**
     * 配置选项
     * @var array
     */
    protected static array $options = [];
    
    /**
     * 初始化
     * 
     * @param array $options 配置选项
     * @return void
     */
    public static function initialize(array $options = []): void
    {
        self::$options = array_merge([
            'lite_mode' => false,
            'pool_enabled' => true,
            'cache_enabled' => true,
            'pool_config' => [
                'max_size' => 100,
                'min_size' => 5,
            ],
            'cache_size' => 1000,
        ], $options);
        
        self::$liteMode = self::$options['lite_mode'];
        self::$poolEnabled = self::$options['pool_enabled'];
        self::$cacheEnabled = self::$options['cache_enabled'];
        
        // 配置消息池
        if (self::$poolEnabled) {
            MessagePool::setPoolConfig(self::$options['pool_config']);
            MessagePool::setCacheSize(self::$options['cache_size']);
        }
    }
    
    /**
     * 创建消息对象
     * 
     * @param string $className 消息类名
     * @return Message 消息对象
     */
    public static function createMessage(string $className): Message
    {
        // 如果启用对象池，尝试从池中获取
        if (self::$poolEnabled) {
            $message = MessagePool::getMessage($className);
            if ($message !== null) {
                return $message;
            }
        }
        
        // 创建新对象
        $message = new $className();
        
        // 如果启用Lite模式，尝试应用优化
        if (self::$liteMode && method_exists($message, 'setUseLiteRuntime')) {
            $message->setUseLiteRuntime(true);
        }
        
        return $message;
    }
    
    /**
     * 释放消息对象
     * 
     * @param Message $message 消息对象
     * @return void
     */
    public static function releaseMessage(Message $message): void
    {
        // 如果启用对象池，归还对象到池
        if (self::$poolEnabled) {
            MessagePool::returnMessage($message);
        }
    }
    
    /**
     * 序列化消息
     * 
     * @param Message $message 消息对象
     * @return string 序列化结果
     */
    public static function serialize(Message $message): string
    {
        // 如果启用缓存，尝试从缓存获取
        if (self::$cacheEnabled) {
            $cached = MessagePool::getSerializationCache($message);
            if ($cached !== null) {
                return $cached;
            }
        }
        
        // 执行序列化
        $data = $message->serializeToString();
        
        // 如果启用缓存，保存到缓存
        if (self::$cacheEnabled) {
            MessagePool::setSerializationCache($message, $data);
        }
        
        return $data;
    }
    
    /**
     * 反序列化消息
     * 
     * @param string $data 序列化数据
     * @param string $className 消息类名
     * @return Message 消息对象
     */
    public static function deserialize(string $data, string $className): Message
    {
        // 创建消息对象
        $message = self::createMessage($className);
        
        // 反序列化
        $message->mergeFromString($data);
        
        return $message;
    }
    
    /**
     * 预热消息池
     * 
     * @param array $classNames 消息类名数组
     * @return void
     */
    public static function warmUp(array $classNames): void
    {
        if (self::$poolEnabled) {
            MessagePool::warmUp($classNames);
        }
    }
    
    /**
     * 清空缓存
     * 
     * @return void
     */
    public static function clearCache(): void
    {
        if (self::$poolEnabled) {
            MessagePool::clearSerializationCache();
        }
    }
    
    /**
     * 获取统计信息
     * 
     * @return array 统计信息
     */
    public static function getStats(): array
    {
        $stats = [
            'lite_mode' => self::$liteMode,
            'pool_enabled' => self::$poolEnabled,
            'cache_enabled' => self::$cacheEnabled,
        ];
        
        if (self::$poolEnabled) {
            $stats['pool'] = MessagePool::getStats();
        }
        
        return $stats;
    }
    
    /**
     * 启用Lite模式
     * 
     * @return void
     */
    public static function enableLiteMode(): void
    {
        self::$liteMode = true;
    }
    
    /**
     * 禁用Lite模式
     * 
     * @return void
     */
    public static function disableLiteMode(): void
    {
        self::$liteMode = false;
    }
    
    /**
     * 启用对象池
     * 
     * @return void
     */
    public static function enablePool(): void
    {
        self::$poolEnabled = true;
    }
    
    /**
     * 禁用对象池
     * 
     * @return void
     */
    public static function disablePool(): void
    {
        self::$poolEnabled = false;
    }
    
    /**
     * 启用缓存
     * 
     * @return void
     */
    public static function enableCache(): void
    {
        self::$cacheEnabled = true;
    }
    
    /**
     * 禁用缓存
     * 
     * @return void
     */
    public static function disableCache(): void
    {
        self::$cacheEnabled = false;
    }
}